package com.kot32.dynamicloadviewlibrary.core;


import com.google.gson.Gson;
import com.kot32.dynamicloadviewlibrary.config.DynamicViewConfig;
import com.kot32.dynamicloadviewlibrary.model.DynamicInfo;
import com.kot32.dynamicloadviewlibrary.util.DownloadTask;
import com.kot32.dynamicloadviewlibrary.util.LogUtil;
import com.kot32.dynamicloadviewlibrary.util.PreferenceManager;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import ohos.agp.utils.TextTool;
import ohos.app.Context;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/**
 * Created by kot32 on 16/9/20.
 */
public class DynamicViewManager {

    private static final String TAG = DynamicViewManager.class.getSimpleName();

    private DynamicViewConfig config;

    private static DynamicViewManager instance;

    private DynamicInfo dynamicInfo;

    private List<DynamicViewGroup> dynamicViewGroups;

    private String updateFileDirPath;
    private String dexOutDirPath;

    private String updateFileFullPath;

    OkHttpClient client = new OkHttpClient();

    public static final String KEY_VIEW_VERSION = "dynamic_view_info";
    public static final String KEY_SHOULD_UPDATE = "dynamic_should_update";

    public static DynamicViewManager getInstance(DynamicViewConfig config) {
        if (instance == null) {
            instance = new DynamicViewManager(config);
        }
        return instance;
    }

    private DynamicViewManager(DynamicViewConfig config) {
        this.config = config;
        this.dynamicViewGroups = new ArrayList<>();
    }

    public static DynamicViewManager getInstance() {
        if (instance == null) {
            LogUtil.i("Please set config first.");
        }
        return instance;
    }

    private boolean shouldUpdate;

    public void init() {
        PreferenceManager.init(config.getContext());
        initFiles();

        if (TextTool.isNullOrEmpty(config.getGetUpdateInfoApi())) {
            LogUtil.i("Please set the apiUrl of update");
            return;
        }
        shouldUpdate = (boolean) PreferenceManager.getPreference(KEY_SHOULD_UPDATE, false);
        String oldViewInfoJson = (String) PreferenceManager.getPreference(KEY_VIEW_VERSION, "");

        if (!TextTool.isNullOrEmpty(oldViewInfoJson)) {
            try {
                dynamicInfo = new Gson().fromJson(oldViewInfoJson, DynamicInfo.class);
            }catch (Exception e){
                e.printStackTrace();
            }
        }

        if (dynamicInfo != null) {
            updateFileFullPath = updateFileDirPath + "/" + dynamicInfo.version + "_" + dynamicInfo.fileName;
            if (shouldUpdate) {
                initResource(updateFileFullPath);
            }
            File file = new File(updateFileFullPath);
            if (!file.exists()) {
                fetchUpdate();
            }
        }

        new Thread(new Runnable() {
            @Override
            public void run() {
                Request request = new Request.Builder()
                        .url(config.getGetUpdateInfoApi())
                        .build();
                try {
//                    Response response = client.newCall(request).execute();
//                    String info = "{\"version\":2,\"downLoadPath\":\"http://obfgb7oet.bkt.clouddn.com/patch101.apk\",\"fileName\":\"plugin-I.apk\",\"viewInfo\":[{\"packageName\":\"com.kot32.testdynamicviewproject.MyButton\",\"uuid\":\"test\",\"layoutParams\":{\"width\":100,\"height\":100}},{\"packageName\":\"com.kot32.testdynamicviewproject.MyButton1\",\"uuid\":\"test_activity\",\"layoutParams\":{\"width\":-1,\"height\":-1}}]}";
                    String info = "{\"version\":3,\"downLoadPath\":\"http://obfgb7oet.bkt.clouddn.com/patch101.apk\",\"fileName\":\"plugin.hap\",\"viewInfo\":[{\"packageName\":\"com.ut.plugin.component.View\",\"uuid\":\"test\",\"layoutParams\":{\"width\":300,\"height\":300}},{\"packageName\":\"com.ut.plugin.component.View\",\"uuid\":\"test_activity\",\"layoutParams\":{\"width\":-1,\"height\":-1}}]}";
                    DynamicInfo newInfo = new Gson().fromJson(info, DynamicInfo.class);
//                    DynamicInfo newInfo = new Gson().fromJson(response.body().string(), DynamicInfo.class);
                    if (newInfo == null) {
                        return;
                    }
                    if (dynamicInfo == null || newInfo.version > dynamicInfo.version) {
                        if (dynamicInfo != null && dynamicInfo.downLoadPath.equals(newInfo.downLoadPath)) {
                            dynamicInfo.viewInfo = newInfo.viewInfo;
                            PreferenceManager.addStringPreference(KEY_VIEW_VERSION, new Gson().toJson(dynamicInfo));
                            PreferenceManager.addBooleanPreference(KEY_SHOULD_UPDATE, true);
                        } else {
                            //start download apk
                            dynamicInfo = newInfo;
                            fetchUpdate();
                        }

                    }
                } catch (Exception e) {
                    System.out.println(e);
                    e.printStackTrace();
                }

            }
        }).start();

    }


    private void fetchUpdate() {
        updateFileFullPath = updateFileDirPath + "/" + dynamicInfo.version + "_" + dynamicInfo.fileName;
        final String apkPath = updateFileDirPath + "/" + dynamicInfo.version + "_" + dynamicInfo.fileName;

        File apk = new File(apkPath);
//        if (apk.exists()) {
//            //delete the old version but same name apk.
//            apk.delete();
//            return;
//        }

//        new DownloadTask() {
//            @Override
//            protected void onComplete() {
//                PreferenceManager.addStringPreference(KEY_VIEW_VERSION, new Gson().toJson(dynamicInfo));
//                //download complete,when the app restart it will work
//                PreferenceManager.addBooleanPreference(KEY_SHOULD_UPDATE, true);
//            }
//        }.execute(dynamicInfo.downLoadPath, apkPath);
//
//        PreferenceManager.addBooleanPreference(KEY_SHOULD_UPDATE, false);
//        shouldUpdate = false;

        PreferenceManager.addStringPreference(KEY_VIEW_VERSION, new Gson().toJson(dynamicInfo));
        //download complete,when the app restart it will work
        String rawFilePath = "entry/resources/rawfile/plugin.hap";
        copyAndWrite(config.getContext(), apkPath, rawFilePath);
        File apkFile = new File(updateFileFullPath);
        LogUtil.i("file exist: %b", apkFile.exists());

    }

    /**
     * 将asset文件写入缓存
     */
    private boolean copyAndWrite(Context context, String filePath, String rawFilePath){
        try {
            File outFile =new File(filePath);
            if (!outFile.exists()){
                boolean res=outFile.createNewFile();
                if (!res){
                    return false;
                }
            }else {
                if (outFile.length()>10){//表示已经写入一次
                    return true;
                }
            }
            InputStream is = context.getResourceManager().getRawFileEntry(rawFilePath).openRawFile();
            FileOutputStream fos = new FileOutputStream(outFile);
            byte[] buffer = new byte[1024];
            int byteCount;
            while ((byteCount = is.read(buffer)) != -1) {
                fos.write(buffer, 0, byteCount);
            }
            fos.flush();
            is.close();
            fos.close();
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * add resource path to host app.
     */
    private void initResource(String path) {

    }

    public DynamicViewConfig getConfig() {
        return config;
    }

    public DynamicInfo getDynamicInfo() {
        return dynamicInfo;
    }

    public void setDynamicInfo(DynamicInfo dynamicInfo) {
        this.dynamicInfo = dynamicInfo;
    }

    public String getUpdateFileFullPath() {
        return updateFileFullPath;
    }

    public void addViewGroup(DynamicViewGroup viewGroup) {
        if (viewGroup == null) {
            return;
        }
        if (!dynamicViewGroups.contains(viewGroup)) {
            this.dynamicViewGroups.add(viewGroup);
        }
    }

    private void initFiles() {
        updateFileDirPath = config.getContext().getExternalCacheDir() + "/" + config.getUpdateFileDir();
        dexOutDirPath = config.getContext().getExternalCacheDir() + "/" + config.getDexOutDir();
        File f = new File(updateFileDirPath);
        if (!f.exists()) {
            f.mkdirs();
        }
        f = new File(dexOutDirPath);
        if (!f.exists()) {
            f.mkdirs();
        }
    }

    public String getDexOutDirPath() {
        return dexOutDirPath;
    }

    public boolean getShouldUpdate() {
        return shouldUpdate;
    }


    public void clearUpdateCache() {
        File dir = new File(updateFileDirPath);
        if (dir.exists() && dir.isDirectory()) {
            for (File f : dir.listFiles()) {
                if (!f.delete()) {
                    f.delete();
                }
            }
        }
    }

}
